package cn.b.sky.mes.em.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import cn.b.sky.mes.em.enums.EquipmentRepairCode;
import cn.b.sky.mes.em.model.RepairOrderPart;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.runtime.ProcessInstance;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.b.sky.mes.em.dao.RepairOrderDao;
import cn.b.sky.mes.em.model.RepairOrder;
import cn.b.sky.mes.em.model.RepairOrderCause;
import cn.b.sky.mes.em.model.condition.RepairOrderCondition;
import cn.b.sky.mes.em.service.RepairOrderService;
import cn.b.sky.shop.activiti.constans.GlobalDefine;
import cn.b.sky.shop.activiti.enums.ProcessInstanceStatusEnum;
import cn.b.sky.shop.activiti.service.WorkFlowFacade;
import cn.b.sky.common.exception.ImeException;
import cn.b.sky.common.model.BatchJobReport;
import cn.b.sky.common.model.ImeCommon;
import cn.b.sky.common.utils.DatabaseUtils;
import cn.b.sky.common.utils.PropertiesDataBinder;
import cn.b.sky.i18n.utils.LocaleResourceBundle;
import cn.b.sky.user.SecurityContextUtil;
import cn.b.sky.mes.cm.enums.ECodeEnums;
import cn.b.sky.user.service.ECodeService;
import cn.b.sky.user.service.model.ECode;

@Service("repairService")
public class RepairOrderServiceImpl implements RepairOrderService {

  private static final Logger LOGGER = LoggerFactory.getLogger(RepairOrderServiceImpl.class);

  @Resource
  RepairOrderDao repairDao;

  @Resource
  ECodeService eCodeService;

  @Autowired
  private RuntimeService runtimeService;

  @Resource
  WorkFlowFacade workFlowFacade;

  //审核报修单
  @Override
  public void repairOrderAudit(DelegateTask task, String eventName) {

    boolean passFlag = false;
    if (TaskListener.EVENTNAME_COMPLETE.endsWith(eventName)) {
      //获取业务数据处理
      String ispass = "";
      if (task.getVariable(GlobalDefine.WorkFlow.AUDITPARAM) != null) {
        ispass = (String) task.getVariable(GlobalDefine.WorkFlow.AUDITPARAM);
      }
      if (!StringUtils.isBlank(ispass)) {
        passFlag = "0".equals(ispass) ? true : false;
      }
      task.setVariable("auditPass", passFlag);
    }
    if (!passFlag) {
      task.removeVariable(GlobalDefine.WorkFlow.AUDITPARAM);
      return;
    }
    Map<String, Object> operationMap = (Map<String, Object>) task.getVariable(GlobalDefine.WorkFlow.OPERATIONMAP);
    //设置下一个节点的处理人 新增需求，下一个节点处理人在业务数据中获取
    String repairUser = (String) operationMap.get("repairUser");
    if (StringUtils.isBlank(repairUser)) {
      throw ImeException.newException("chooseRepairUser.M,");
    }
    task.setVariable(GlobalDefine.WorkFlow.NEXT_HANDLER, operationMap.get("repairUser"));
    String siteCode = (String) operationMap.get(GlobalDefine.WorkFlow.CUREENTSITECODE);
    String businessKey = (String) operationMap.get(GlobalDefine.WorkFlow.BUSINESSKEY);
    this.doReceiveRepairOrder(businessKey, siteCode);

    task.removeVariable(GlobalDefine.WorkFlow.OPERATIONMAP);
  }

  //维修录入 
  @Override
  public void repairAudit(DelegateTask task, String eventName) {

    Map<String, Object> operationMap = (Map<String, Object>) task.getVariable(GlobalDefine.WorkFlow.OPERATIONMAP);
    PropertiesDataBinder dataBinder = null;
    RepairOrder order = null;

    try {
      dataBinder = PropertiesDataBinder.createBinder(BeanUtils.instantiateClass(RepairOrder.class));
      order = (RepairOrder) dataBinder.getTarget(operationMap);
      if (order != null) {
        String siteCode = (String) operationMap.get(GlobalDefine.WorkFlow.CUREENTSITECODE);
        String orderCode = order.getOrderCode();
        List<RepairOrderCause> causes = order.getCauses();
        for (RepairOrderCause cause : causes) {
          setCreateInfo(cause);
          cause.setOrderCode(orderCode);
          cause.setSiteCode(siteCode);
        }
        List<RepairOrderPart> parts = order.getParts();
        for (RepairOrderPart part : parts) {
          setCreateInfo(part);
          part.setOrderCode(orderCode);
          part.setSiteCode(siteCode);
        }
        order.setSiteCode(siteCode);
        this.doRecordRepairOrder(order, causes, parts);
      }
    } catch (BeanInstantiationException e) {
      LOGGER.error("{}", e);
    } catch (Exception e) {
      LOGGER.error("{}", e);
    }
    task.removeVariable(GlobalDefine.WorkFlow.OPERATIONMAP);
  }

  //报修验证
  @Override
  public void checkOrderAudit(DelegateTask task, String eventName) {

    Map<String, Object> operationMap = (Map<String, Object>) task.getVariable(GlobalDefine.WorkFlow.OPERATIONMAP);
    PropertiesDataBinder dataBinder;
    RepairOrder order = null;
    try {
      dataBinder = PropertiesDataBinder.createBinder(BeanUtils.instantiateClass(RepairOrder.class));
      order = (RepairOrder) dataBinder.getTarget(operationMap);
      if (order != null) {
        order.setStatusECode(EquipmentRepairCode.VALIDATED.getValue());
        order.setSiteCode((String) operationMap.get(GlobalDefine.WorkFlow.CUREENTSITECODE));
        BatchJobReport report = this.doCheckRepairOrder(order);
        LOGGER.debug("checkOrderAudit:" + report.isSuccess());
      }
    } catch (BeanInstantiationException e) {
      LOGGER.error("{}", e);
    } catch (Exception e) {
      LOGGER.error("{}", e);
    }
    task.removeVariable(GlobalDefine.WorkFlow.AUDITPARAM);
    task.removeVariable(GlobalDefine.WorkFlow.OPERATIONMAP);
  }

  //重新申请
  @Override
  public void reportBackEndProcessor(DelegateTask task, String eventName) {

    if (TaskListener.EVENTNAME_COMPLETE.endsWith(eventName)) {
      boolean passFlag = false;
      String ispass = "";
      if (task.getVariable(GlobalDefine.WorkFlow.AUDITPARAM) != null) {
        ispass = (String) task.getVariable(GlobalDefine.WorkFlow.AUDITPARAM);
      }
      if (!StringUtils.isBlank(ispass)) {
        passFlag = "0".equals(ispass) ? true : false;
        task.setVariable("restart", passFlag);
        if (passFlag) {
          //获取业务数据处理
          String processInstanceId = task.getProcessInstanceId();
          ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
              .processInstanceId(processInstanceId).singleResult();
          Map<String, Object> operationMap = (Map<String, Object>) task.getVariable(GlobalDefine.WorkFlow.OPERATIONMAP);
          String siteCode = (String) operationMap.get(GlobalDefine.WorkFlow.CUREENTSITECODE);
          RepairOrder order = repairDao.getOrderByBusinessKey(processInstance.getBusinessKey(), siteCode);
          order.setRequestDateTime(new Date());
          repairDao.updateRepairOrder(order);
        }
        task.removeVariable(GlobalDefine.WorkFlow.AUDITPARAM);
      }
      task.removeVariable(GlobalDefine.WorkFlow.OPERATIONMAP);
    }
  }

  @Override
  public List<RepairOrder> selectRepairOrderListByCondition(RepairOrderCondition condition) {
    if (condition == null) {
      condition = new RepairOrderCondition();
    }
    if (StringUtils.isBlank(condition.getOrderField())) {
      condition.setOrderField("createDateTime");
      condition.setOrderDirection("desc");
    }
    return repairDao.selectRepairOrderListByCondition(condition);
  }

  @Override
  public int selectRepariOrderCountByCondition(RepairOrderCondition condition) {
    if (condition == null) {
      condition = new RepairOrderCondition();
    }
    return repairDao.selectRepariOrderCountByCondition(condition);
  }

  @Override
  public boolean insertRepairOrder(RepairOrder order) {
    if (order == null || StringUtils.isBlank(order.getOrderCode())) {
      return false;
    }

    repairDao.insertRepairOrder(order);
    return true;
  }

  @Override
  public String getRepairOrderStatus(String orderCode, String siteCode) {
    if (StringUtils.isBlank(orderCode) || StringUtils.isBlank(siteCode)) {
      return "";
    }
    return repairDao.getRepairOrderStatus(orderCode, siteCode);
  }

  @Override
  public boolean saveRepairOrderPart(List<RepairOrderPart> parts, String orderCode, String siteCode) {
    int len = parts.size();
    if (len == 0) {
      return true;
    }
    if (StringUtils.isBlank(orderCode)) {
      return false;
    } else {
      repairDao.deleteRepairOrderPart(orderCode, siteCode);
      for (RepairOrderPart part : parts) {
        repairDao.insertRepairOrderPart(part);
      }
    }
    return true;

  }

  @Override
  public boolean saveRepairOrderCause(List<RepairOrderCause> causes, String orderCode, String siteCode) {
    int len = causes.size();
    if (len == 0) {
      return true;
    }
    if (StringUtils.isBlank(orderCode)) {
      return false;
    } else {
      repairDao.deleteRepairOrderCause(orderCode, siteCode);
      for (RepairOrderCause cause : causes) {
        repairDao.insertRepairOrderCause(cause);
      }
    }
    return true;

  }

  //接单
  @Override
  public BatchJobReport doReceiveRepairOrder(String businessKey, String siteCode) {

    if (StringUtils.isBlank(businessKey) || StringUtils.isBlank(siteCode)) {
      return new BatchJobReport("", LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
          SecurityContextUtil.getLanguageCode(), "parameterError.M"), false);
    }
    String message = businessKey;
    String cause = "";
    boolean success = true;
    RepairOrder order = this.getOrderByBusinessKey(businessKey, siteCode);
    if (!EquipmentRepairCode.PENDING.getValue().equals(order.getStatusECode())) {
      success = false;
      ECode statusECode = eCodeService.selectEcodeByECodeTypeAndLanguageCodeAndECode(order.getStatusECode(),
          ECodeEnums.EQUIPMENTREPAIRSTATUS.getCode(), SecurityContextUtil.getLanguageCode());
      cause = LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
          SecurityContextUtil.getLanguageCode(), "RepairStatusAlreadyIs.M")
          + statusECode.geteCodeText();
      return new BatchJobReport(message, cause, success);
    } else {
      order.setSiteCode(siteCode);
      order.setStatusECode(EquipmentRepairCode.PROCESSING.getValue());
      order.setReceiveUser(SecurityContextUtil.getCurrentUserName());
      order.setReceiveDateTime(new Date());
      repairDao.updateRepairOrder(order);
    }
    return new BatchJobReport(message, cause, success);
  }

  //录入
  @Override
  public BatchJobReport doRecordRepairOrder(RepairOrder order, List<RepairOrderCause> orderCauses,
      List<RepairOrderPart> parts) {
    String siteCode = order.getSiteCode();
    String orderCode = order.getOrderCode();
    if (StringUtils.isBlank(orderCode) || StringUtils.isBlank(siteCode)) {
      return new BatchJobReport("", LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
          SecurityContextUtil.getLanguageCode(), "parameterError.M"), false);
    }
    String message = order.getOrderCode();
    String cause = "";
    boolean success = true;
    order.setStatusECode(EquipmentRepairCode.PROCESSED.getValue());
    repairDao.updateRepairOrder(order);
    if (orderCauses.size() > 0) {
      this.saveRepairOrderCause(orderCauses, orderCode, siteCode);
    }
    if (parts.size() > 0) {
      this.saveRepairOrderPart(parts, orderCode, siteCode);
    }
    return new BatchJobReport(message, cause, success);
  }

  //验收
  @Override
  public BatchJobReport doCheckRepairOrder(RepairOrder order) {
    String siteCode = order.getSiteCode();
    String orderCode = order.getOrderCode();
    if (StringUtils.isBlank(orderCode) || StringUtils.isBlank(siteCode)) {
      return new BatchJobReport("", LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
          SecurityContextUtil.getLanguageCode(), "parameterError.M"), false);
    }
    String message = orderCode;
    String cause = "";
    boolean success = true;
    RepairOrder order1 = new RepairOrder();
    order1.setOrderCode(order.getOrderCode());
    order1.setSiteCode(order.getSiteCode());
    order1.setCheckMemo(order.getCheckMemo());
    order1.setCheckResult(order.getCheckResult());
    order1.setCheckUser(order.getCheckUser());
    order1.setShutdownEndDatetime(order.getShutdownEndDatetime());
    order1.setCheckDateTime(new Date());
    order1.setStatusECode(order.getStatusECode());
    repairDao.updateRepairOrder(order1);
    return new BatchJobReport(message, cause, success);
  }

  @Override
  public RepairOrder getRepairOrder(String orderCode, String siteCode) {
    if (StringUtils.isBlank(orderCode) || StringUtils.isBlank(siteCode)) {
      return null;
    } else {
      return repairDao.getRepairOrder(orderCode, siteCode);
    }
  }

  public boolean validateECode(String orderCode, String siteCode, String eCode) {
    if (StringUtils.isBlank(orderCode) || StringUtils.isBlank(siteCode) || StringUtils.isBlank(eCode)) {
      return false;
    }
    String ecode = this.getRepairOrderStatus(orderCode, siteCode);
    return ecode.equals(eCode);
  }

  public boolean validateECode(RepairOrder order, String eCode) {
    return validateECode(order.getOrderCode(), order.getSiteCode(), eCode);
  }

  public ECode getECode(String eCode) {

    return eCodeService.selectEcodeByECodeTypeAndLanguageCodeAndECode(eCode,
        ECodeEnums.EQUIPMENTREPAIRSTATUS.getCode(), SecurityContextUtil.getLanguageCode());
  }

  @Override
  public BatchJobReport deleteRepairOrders(String orderCode, String siteCode) {
    if (!StringUtils.isBlank(orderCode)) {
      String message = orderCode;
      String cause = "";
      boolean success = true;
      String eCode = this.getRepairOrderStatus(orderCode, siteCode);
      if (!eCode.equals(EquipmentRepairCode.PENDING.getValue())) {
        success = false;
        ECode ecode = eCodeService.selectEcodeByECodeTypeAndLanguageCodeAndECode(eCode,
            ECodeEnums.EQUIPMENTREPAIRSTATUS.getCode(), SecurityContextUtil.getLanguageCode());
        cause = LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
            SecurityContextUtil.getLanguageCode(), "RepairStatusAlreadyIs.M")
            + ecode.geteCodeText();
        return new BatchJobReport(message, cause, success);
      }
      RepairOrder order = repairDao.getRepairOrder(orderCode, siteCode);
      String processStatus = workFlowFacade.getProcessInstanceStatus(order.getBusinessKey(), siteCode);
      if (!StringUtils.isBlank(processStatus) && !ProcessInstanceStatusEnum.NOTSTART.getValue().equals(processStatus)) {
        success = false;
        cause = LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
            SecurityContextUtil.getLanguageCode(), "processIsInProcessCanNotDelete.M");
        return new BatchJobReport(message, cause, success);
      }
      try {
        repairDao.deleteRepairOrder(orderCode, siteCode);
      } catch (Exception e) {
        LOGGER.error("{}", e);
        success = false;
        String errorMsg = e.getMessage();
        if (DatabaseUtils.isConstraintsError(e.getMessage())) {
          //外键删除已存在提示
          errorMsg = LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
              SecurityContextUtil.getLanguageCode(), "dataBaseOperationPkFail.M")
              + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                  SecurityContextUtil.getLanguageCode(), "notDelete.M");
        }
        cause = errorMsg;
      }
      return new BatchJobReport(message, cause, success);
    } else {
      return new BatchJobReport("", "equipment is null", false);
    }
  }

  @Override
  public BatchJobReport modifyRepairOrder(RepairOrder order) {
    String orderCode = order.getOrderCode();
    String siteCode = order.getSiteCode();
    String cause = "";
    boolean success = true;
    if (StringUtils.isBlank(orderCode)) {
      success = false;
      cause = LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
          SecurityContextUtil.getLanguageCode(), "parameterError.M");
      return new BatchJobReport("", cause, success);
    }
    String eCode = this.getRepairOrderStatus(orderCode, siteCode);
    if (!eCode.equals(EquipmentRepairCode.PENDING.getValue())) {
      success = false;
      ECode ecode = eCodeService.selectEcodeByECodeTypeAndLanguageCodeAndECode(eCode,
          ECodeEnums.EQUIPMENTREPAIRSTATUS.getCode(), SecurityContextUtil.getLanguageCode());
      cause = LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
          SecurityContextUtil.getLanguageCode(), "RepairStatusAlreadyIs.M")
          + ecode.geteCodeText();
    } else {
      repairDao.modifyRepairOrder(order);
    }
    return new BatchJobReport("", cause, success);
  }

  @Override
  public List<RepairOrder> getRepairOrderWithCausePart(String id, String siteCode) {
    return repairDao.getRepairOrderWithCausePart(id, siteCode);
  }

  @Override
  public List<RepairOrderCause> getRepairOrderCause(String orderCode, String siteCode) {
    return repairDao.getRepairOrderCause(orderCode, siteCode);
  }

  @Override
  public List<RepairOrderPart> getRepairOrderPart(String orderCode, String siteCode) {
    return repairDao.getRepairOrderPart(orderCode, siteCode);
  }

  @Override
  public RepairOrder getOrderByBusinessKey(String bussinessKey, String siteCode) {
    if (StringUtils.isBlank(bussinessKey) || StringUtils.isBlank(siteCode)) {
      return null;
    } else {
      return repairDao.getOrderByBusinessKey(bussinessKey, siteCode);
    }
  }

  public void setCreateInfo(ImeCommon imeCommon) {
    imeCommon.setCreateDateTime(new Date());
    imeCommon.setModifyDateTime(new Date());
    imeCommon.setCreateUser(SecurityContextUtil.getCurrentUserName());
    imeCommon.setModifyUser(SecurityContextUtil.getCurrentUserName());
  }

  @Override
  public void doReceiveRepairOrderByBusinessKey(String orderCode, String siteCode) {
    // Do nothing
  }

}
